package com.lyc.iotdb.common.component;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import io.github.xingchuan.sql.engine.FlashSqlEngine;
import io.github.xingchuan.sql.provider.impl.DefaultMybatisSqlParseProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;

import static io.github.xingchuan.sql.provider.impl.DefaultMybatisSqlParseProvider.MYBATIS_SQL_TYPE;

/**
 * sql 拼接模板引擎
 *
 * @author kisang
 * @version 1.0
 * @date 2023/11/24 11:59
 */
@Component
@Slf4j
public class FlashSqlEngineTool {
    private static FlashSqlEngine flashSqlEngine;

    @Value("${iotdb.mapper-locations}")
    private String mapperLocations;


    /**
     * 初始化
     *
     * @return FlashSqlEngine
     */
    @Bean
    public FlashSqlEngine initFlashSqlEngine() throws IOException {
        if (flashSqlEngine == null) {
            flashSqlEngine = new FlashSqlEngine();
            // 提供了默认的mybatis的渲染机制，如果需要别的，只需要提供对应的sqlParseProvider即可
            flashSqlEngine.registerSqlParseProvider(MYBATIS_SQL_TYPE, new DefaultMybatisSqlParseProvider());
            String directoryPath = "classpath:mapper/**/*.xml";
            if (StrUtil.isNotEmpty(mapperLocations)) {
                if (!mapperLocations.contains("classpath:")) {
                    log.info("The current path configuration is invalid, mapperLocations {} , so load the default path resource", mapperLocations);
                } else {
                    directoryPath = mapperLocations;
                }
            }
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(directoryPath);
            for (Resource resource : resources) {
                InputStream inputStream = resource.getInputStream();
                flashSqlEngine.loadConfig(inputStream);
            }
        }
        return flashSqlEngine;
    }

    /**
     * 拼接sql
     *
     * @param sqlId
     * @param params
     * @return
     */
    public String parseSqlWithSqlId(String sqlId, JSONObject params) {
        return flashSqlEngine.parseSqlWithSqlId(sqlId, params);
    }

    /**
     * 获取加载文件
     *
     * @param mapperLocations 加载文件路径
     * @return 待加载文件路径
     */
    public List<File> getFilesInDirectory(String mapperLocations) {
        // 默认场合加载mapper/iotdb/路径下的xml文件
        String directoryPath = "classpath:mapper/**/*.xml";
        if (StrUtil.isNotEmpty(mapperLocations)) {
            if (!mapperLocations.contains("classpath:")) {
                log.info("The current path configuration is invalid, mapperLocations {} , so load the default path resource", mapperLocations);
            } else {
                directoryPath = mapperLocations;
            }
        }
        List<File> files = new ArrayList<>();
        try {
            //如何获取resource下的文件？【注意：即使打成jar包也得有效】
            ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resourcePatternResolver.getResources(directoryPath);
            for (Resource resource : resources) {
                //获取文件，在打成jar包后，通过url来获取文件，则路径是正确的
                File file = new File(resource.getURL().getFile());
                log.info("load getAbsolutePath file {}", file.getAbsolutePath());
                log.info("load getCanonicalPath file {}", file.getCanonicalPath());
                files.add(file);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return files;
    }

    public List<Path> getFilesInDirectory() {
        String directoryPath = "mapper/iotdb/";
        String filePattern = "*.xml";
        List<Path> files = new ArrayList<>();
        try {
            ClassPathResource resource = new ClassPathResource(directoryPath);
            try (InputStream inputStream = resource.getInputStream()) {
                Path tempDirectory = Files.createTempDirectory("temp");
                Path tempFile = tempDirectory.resolve("temp.xml");
                Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
                Path path = tempFile.getParent();
                if (Files.isDirectory(path)) {
                    Files.walk(path, FileVisitOption.FOLLOW_LINKS)
                            .filter(p -> Files.isRegularFile(p) && p.getFileName().toString().endsWith(".xml"))
                            .forEach(files::add);
                }
                Files.deleteIfExists(tempFile);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return files;
    }

}
